/* eslint-disable unicorn/prevent-abbreviations */
/* eslint-disable no-unneeded-ternary */
// @ts-nocheck

/**
 * modified by @tinymce/tinymce-vue@3.2.8 component
 */

/**
 * Copyright (c) 2018-present, Ephox, Inc.
 *
 * This source code is licensed under the Apache 2 license found in the
 * LICENSE file in the root directory of this source tree.
 *
 */

import { publicPath } from '@/api/constants'
import { ThisTypedComponentOptionsWithRecordProps } from 'vue/types/options'
import { CreateElement, Vue } from 'vue/types/vue'

//  import { getTinymce } from '../TinyMCE'
import { initEditor, isTextarea, mergePlugins, uuid } from './tinymce-utils'
//  import { editorProps, IPropTypes } from './EditorPropTypes'

type CopyProps<T> = { [P in keyof T]: any }

interface IPropTypes {
  apiKey: string
  cloudChannel: string
  id: string
  init: any
  initialValue: string
  outputFormat: 'html' | 'text'
  inline: boolean
  modelEvents: string[] | string
  plugins: string[] | string
  tagName: string
  toolbar: string[] | string
  value: string
  disabled: boolean
  tinymceScriptSrc: string
}

const editorProps: CopyProps<IPropTypes> = {
  apiKey: String,
  cloudChannel: String,
  id: String,
  init: Object,
  initialValue: String,
  inline: Boolean,
  modelEvents: [String, Array],
  plugins: [String, Array],
  tagName: String,
  toolbar: [String, Array],
  value: String,
  disabled: Boolean,
  tinymceScriptSrc: String,
  outputFormat: {
    type: String,
    validator: (prop: string) => prop === 'html' || prop === 'text',
  },
}

const getGlobal = (): any => (typeof window !== 'undefined' ? window : global)

const getTinymce = () => {
  const global = getGlobal()

  return global && global.tinymce ? global.tinymce : null
}

export interface IEditor extends Vue {
  $props: Partial<IPropTypes>
}

const renderInline = (h: CreateElement, id: string, tagName?: string) => {
  return h(tagName ? tagName : 'div', {
    attrs: { id },
  })
}

const renderIframe = (h: CreateElement, id: string) => {
  return h('textarea', {
    attrs: { id },
    style: { visibility: 'hidden' },
  })
}

const initialise = (ctx: IEditor) => () => {
  const finalInit = {
    ...ctx.$props.init,
    readonly: ctx.$props.disabled,
    selector: `#${ctx.elementId}`,
    menubar: false,
    statusbar: false,
    language: 'zh_CN',
    language_url: `${publicPath}/js/tinymce/langs/zh_CN.js`,
    plugins: mergePlugins(
      ctx.$props.init && ctx.$props.init.plugins,
      ctx.$props.plugins
    ),
    toolbar: ctx.$props.toolbar || (ctx.$props.init && ctx.$props.init.toolbar),
    inline: ctx.inlineEditor,
    setup: (editor: any) => {
      ctx.editor = editor
      editor.on('init', (e: Event) => initEditor(e, ctx, editor))

      if (ctx.$props.init && typeof ctx.$props.init.setup === 'function') {
        ctx.$props.init.setup(editor)
      }
    },
  }

  if (isTextarea(ctx.element)) {
    ctx.element.style.visibility = ''
    ctx.element.style.display = ''
  }

  getTinymce().init(finalInit)
}

export const Editor: ThisTypedComponentOptionsWithRecordProps<
  Vue,
  {},
  {},
  {},
  IPropTypes
> = {
  props: editorProps,
  created() {
    this.elementId = this.$props.id || uuid('tiny-vue')
    this.inlineEditor =
      (this.$props.init && this.$props.init.inline) || this.$props.inline
    this.initialized = false
  },
  watch: {
    disabled() {
      ;(this as any).editor.setMode(this.disabled ? 'readonly' : 'design')
    },
  },
  mounted() {
    this.element = this.$el

    if (getTinymce() !== null) {
      initialise(this)()
    } /* else if (this.element && this.element.ownerDocument) {
      const channel = this.$props.cloudChannel ? this.$props.cloudChannel : '5'
      const apiKey = this.$props.apiKey ? this.$props.apiKey : 'no-api-key'

      const scriptSrc = isNullOrUndefined(this.$props.tinymceScriptSrc) ?
        `https://cdn.tiny.cloud/1/${apiKey}/tinymce/${channel}/tinymce.min.js` :
        this.$props.tinymceScriptSrc

      ScriptLoader.load(
        this.element.ownerDocument,
        scriptSrc,
        initialise(this)
      )
    } */
  },
  beforeDestroy() {
    if (getTinymce() !== null) {
      getTinymce().remove(this.editor)
    }
  },
  deactivated() {
    if (!this.inlineEditor) {
      this.cache = this.editor.getContent()
      getTinymce()?.remove(this.editor)
    }
  },
  activated() {
    if (!this.inlineEditor && this.initialized) {
      initialise(this)()
    }
  },
  render(h: any) {
    return this.inlineEditor
      ? renderInline(h, this.elementId, this.$props.tagName)
      : renderIframe(h, this.elementId)
  },
}

export default Editor
